python基础第十七节

17.1 闭包

闭包是指在一个函数内部定义的函数,并且这个内部函数可以访问外部函数的变量、参数。换句话说,闭包是一个包含了函数及其相关引用环境的组合体。
在Python中,当一个函数返回了内部函数的引用时,这个内部函数可以访问并操作外部函数的局部变量,它就创建了一个闭包, 即使外部函数已经执行完毕,它的局部变量仍然可以被内部函数所使用。
闭包的主要特点是可以将数据和行为捆绑在一起,形成一个独立的环境,而不会与其他部分的代码发生冲突。通过闭包,我们可以实现一些高级的编程技巧,如在函数内部创建私有变量、实现函数工厂或装饰器等.
总结:

  1. 闭包可以保证数据安全.
  2. 内层函数对外层函数非全局变量的引用, 就会形成闭包.
  3. 内部函数可以访问外部函数的变量和参数,即使外部函数已经执行完毕。
  4. 外部函数的局部变量在闭包中被保存,形成了一个私有的环境。
  5. 闭包可以捕获和保留外部函数的状态信息,使得函数的状态得以保持和更新。
  6. 被引用到的非全局变量也称自由变量, 这个自由变量会与内层函数产生一个绑定关系
    闭包是一种强大的编程技术,它可以使代码更加模块化、可维护和可重用。通过使用闭包,我们可以在函数内部创建和维护状态,而不必依赖全局变量或其他复杂的机制。这使得我们的代码更加清晰、可靠,并且更容易扩展和修改。
    案例1: 幂的计算
def power(exponent):

    def calculate_power(base):
        return base ** exponent

    return calculate_power

案例2: 计算每天的平均开销.
案例3: 模拟购物车.

17.2 装饰器

Python装饰器是一种用于修改函数或类行为的特殊函数。它们提供了一种简洁的方式来对现有函数或类进行扩展、修饰或包装,而无需修改它们的源代码。装饰器通常用于在不影响原始函数或类定义的情况下,添加额外的功能或行为。
装饰器本质上是一个函数,它接受一个函数作为输入,并返回一个新的函数。装饰器函数通常在内部定义一个闭包函数,用于包装原始函数,添加额外的逻辑或功能。装饰器函数可以访问原始函数的参数和返回值,并可以在调用前后执行自定义的操作.
装饰器提供了一种简洁而灵活的方式来修改函数的功能,使得我们可以在不改变原代码的情况下添加额外的功能. 用一句话来说就是: 装饰器就是创建一个闭包函数, 在闭包函数的内部调用目标函数, 然后添加相应的功能.
装饰器的语法:
在Python中,装饰器是通过使用@符号来应用的。它可以直接放在函数的定义之前,用于修饰该函数。以下是装饰器的基本语法:

@decorator
def func():
    # 函数定义和实现
    pass

装饰器的应用场景:
装饰器在实际开发中有许多应用场景,以下是一些常见的例子:

17.3 生成器

生成器
生成器是一种特殊类型的函数,可以按需生成一系列的值,而不是一次性将所有值都计算出来并存储在内存中。生成器可以大大节省内存消耗,特别适用于处理大型数据集或无限序列。
yield语句
生成器函数是一种定义生成器的方法。它使用关键字yield来定义生成器的每个值。当生成器函数被调用时,它不会立即执行函数体的所有代码,而是在每次调用生成器的__next__()方法时执行一部分代码,并在遇到yield语句时返回一个值。yieldreturn 是在 Python 中用于返回值的两个关键字,它们在功能和用法上有一些区别。

生成器通过next()函数或迭代语句来逐个获取生成器的值。生成器会记录它的内部状态,因此每次调用next()函数时会从上次停止的地方继续执行。

生成器表达式

生成器表达式是一种简洁的语法,用于快速创建生成器。它的语法与列表推导式类似,但使用圆括号而不是方括号。生成器表达式可以在需要时逐个生成值,而不是一次性生成所有值。

下面是一个生成器表达式的示例,它生成了一个包含1到10之间所有偶数的生成器:

 even_numbers = (x for x in range(1, 11) if x % 2 == 0)

生成器的优势

使用生成器有以下几个优势:

生成器是Python中非常强大和灵活的工具,可以优化代码的性能和内存消耗,并简化处理大型数据集和无限序列的操作。通过掌握生成器的概念和使用方法,可以提高代码的效率和可读性.

生成器的工作原理
生成器的工作原理是通过迭代器协议来实现的。生成器函数使用yield语句将值生成出来,并在生成值后暂停执行,将控制权交还给调用者。当调用者请求下一个值时,生成器函数会从上次暂停的地方继续执行,生成下一个值,并再次暂停。

这种逐步生成值的方式使得生成器可以有效地处理大量的数据或无限的序列,而不会一次性占用大量的内存空间。